<template>
    <div :is="field.tag" v-bind="caseProps" v-on="castEvents" :disabled="!field.enable" :field="field">
        <!-- 文本组件 -->
        <span v-if="field.key === 'text'">{{ field.value }}</span>
        <!-- 按钮组件 -->
        <template v-else-if="field.key === 'button'">
            {{ field.valueStr }}
        </template>
        <!-- 默认插槽 -->
        <template v-else-if="castDefaultSlots">
            <form-item :field="slot" v-for="(slot, index) in castDefaultSlots" :key="'default' + index"></form-item>
        </template>
        <!-- 其他插槽 -->
        <template v-else-if="castOtherSlots">
            <form-item :field="slot.field" v-for="(slot, index) in castOtherSlots" :slot="slot.name" :key="'slot' + index"></form-item>
        </template>
    </div>
</template>
<script>
export default {
    name: 'FormItem',
    inject: ['form'],
    props: {
        field: {
            type: Object,
            required: true
        }
    },
    data() {
        return {
            // 是否显示
            show: true,
            // 是否启用
            enable: true
        };
    },
    computed: {
        // 组装属性
        caseProps() {
            const _this = this;
            let res = Object.fromEntries(
                Object.entries(this.field.props).map(item => {
                    return [item[0], typeof item[1] === 'function' ? item[1].call(_this.field) : item[1]];
                })
            );
            res = Object.assign(res, this.$attrs);
            return res;
        },
        // 组装事件
        castEvents() {
            const _this = this;
            let res = Object.fromEntries(
                Object.entries(this.field.events).map(item => {
                    let fun = _this.$listeners[item[0]];
                    return [
                        item[0],
                        function($event) {
                            eval(item[1]);
                            fun && fun();
                        }.bind(this.form)
                    ];
                })
            );
            res = Object.assign(this.$listeners, res);
            return res;
        },
        // 组装默认插槽
        castDefaultSlots() {
            let res = null;
            try {
                let slots = this.field.slots;
                if (typeof slots === 'function') {
                    slots = slots();
                }
                res = (slots.default && slots.default()) || null;
            } catch (e) {
                console.warn(e);
            }
            return res;
        },
        // 组装其他插槽
        castOtherSlots() {
            let slots = this.field.slots;
            if (typeof slots === 'function') {
                slots = slots();
            }
            let res = Object.entries(slots)
                .filter(item => item[0] !== 'default')
                .map(item => {
                    return {
                        name: item[0],
                        field: typeof item[1] === 'function' ? item[1]() : item[1]
                    };
                });
            return res;
        }
    },
    watch: {
        // 同步更新表单数据
        'field.value': {
            immediate: true,
            handler(value, old) {
                let obj = {};
                obj[this.field.field] = value;
                this.form.formObj.setFieldsValue(obj);
            }
        }
    }
};
</script>

<style lang="scss" scoped></style>
